package com.borya.service.web.impl;

import java.time.Clock;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map.Entry;

import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.borya.constant.RedisConstant;
import com.borya.dao.UserDAO;
import com.borya.dao.WebUserDAO;
import com.borya.framework.annotation.Autowired;
import com.borya.framework.annotation.Component;
import com.borya.framework.util.ObjectUtils;
import com.borya.model.db.Merchant;
import com.borya.model.db.ModelInfo;
import com.borya.model.db.Scope;
import com.borya.model.db.User;
import com.borya.model.entity.SelfRegistering;
import com.borya.service.impl.BaseServiceImpl;
import com.borya.service.web.WebUserService;
import com.borya.statuscode.StatusCode;
import com.borya.util.Constant;
import com.borya.util.DateUtils;
import com.borya.util.StringUtil;

@Component("webUserServiceImpl")
public class WebUserServiceImpl extends BaseServiceImpl implements WebUserService {

	private Logger log = Logger.getLogger(getClass());

	private final int SMS_TIMEOUT = Constant.SMS_TIMEOUT_SECOND;
	private final int PAGE_TIMEOUT = Constant.PAGE_TIMEOUT;
	private final int USER_TIMEOUT = Constant.USER_TIMEOUT;
	private final String MSG_INGO = Constant.MSG_INGO;

	@Autowired("webUserDAOImpl")
	private WebUserDAO webUserDAO;

	@Autowired("userDAOImpl")
	private UserDAO userDAO;

	@Override
	public String login(JSONObject json) {
		try {
			if (!json.containsKey("userName") || json.getString("userName").equals("")) {
				log.warn("login[参数userName错误]");
				return StatusCode.PARAM_ERROR.toJSON("参数 用户名 错误");
			}
			if (checkSessionId(json)) {
				log.warn("cookie对应不上，错误的请求");
				return StatusCode.TOKEN_EXPIRED.toJSON("请登录");
			}
			if (!json.containsKey("code") || json.getString("code").equals("")) {
				log.warn("login[参数code错误]");
				return StatusCode.PARAM_ERROR.toJSON("参数 检验码 错误");
			}

			String phone = webUserDAO.checkUser(json.getString("userName"));
			if (phone == null || phone.equals("")) {
				log.warn("用户资料错误，phone=" + phone);
				return StatusCode.USER_NOT_FOUND.toJSON("用户不存在");
			}
			String code = webUserDAO.redis_get(RedisConstant.CODE + phone);
			if (code == null) {
				log.warn(json.getString("userName") + "用户验证码超时");
				return StatusCode.SYSTEM_EXCEPTION.toJSON("验证码已过期，请重新获取");
			}
			if (!code.equals(json.getString("code"))) {
				log.warn(json.getString("userName") + "用户验证码错误");
				return StatusCode.SYSTEM_EXCEPTION.toJSON("验证码输入错误，请重新输入");
			}
			final String curTime = String.valueOf(System.currentTimeMillis());
			webUserDAO.redis_set(RedisConstant.LIVING + json.getString("userName"), curTime);
			webUserDAO.redis_expire(RedisConstant.LIVING + json.getString("userName"), USER_TIMEOUT);
			webUserDAO.redis_del(RedisConstant.CODE + phone);
			return StatusCode.SUCCESS.toJSON();
		} catch (Exception e) {
			log.error(e.getMessage(), e);
			return StatusCode.SYSTEM_EXCEPTION.toJSON();
		}
	}

	@Override
	public String sentCode(JSONObject json) {
		try {
			if (!json.containsKey("userName") || json.getString("userName").equals("")) {
				log.warn("sentCode[参数userName错误]");
				return StatusCode.PARAM_ERROR.toJSON("参数 用户名 错误");
			}
			setSessionId(json);
			String phone = webUserDAO.checkUser(json.getString("userName"));
			if (phone == null || phone.equals("")) {
				log.warn("用户资料错误，phone=" + phone);
				return StatusCode.USER_NOT_FOUND.toJSON("用户不存在");
			}
			String result = process_sms(phone);
			if (result == null) {
				return StatusCode.SUCCESS.toJSON();
			} else {
				return result;
			}
		} catch (Exception e) {
			log.error(e.getMessage(), e);
			return StatusCode.SYSTEM_EXCEPTION.toJSON();
		}
	}

	/**
	 * 向用户手机发送一条动态验证码
	 * 
	 * @param phone
	 * @return
	 */
	private String process_sms(String phone) {
		String code = webUserDAO.redis_get(RedisConstant.CODE + phone);
		// 短信内容不存在，或者超时了，重新发送
		if (code == null) {
			String authCode = StringUtil.randomNumberString(6);
			if (Constant.IS_TEST) {
				log.info("测试环境验证码写死");
				authCode = "666666";
			}
			String content = "网页开户登录的验证码为：" + authCode + "";

			boolean ok = sendMsg(phone, content);
			if (ok) {
				webUserDAO.redis_set(RedisConstant.CODE + phone, authCode);
				webUserDAO.redis_expire(RedisConstant.CODE + phone, SMS_TIMEOUT);
				log.info("[SMS] 向用户:" + phone + "发送短信验证码成功");
				return null;
			} else {
				log.info("[SMS] 向用户：" + phone + "发送短信验证码失败");
				return StatusCode.SYSTEM_EXCEPTION.toJSON("获取短信验证码失败，请稍后再试");
			}
		} else {
			log.info("[SMS] 短信验证码已向用户：" + phone + "发送出去了");
			return StatusCode.SUCCESS.toJSON("验证码已发送，请勿重复请求");
		}
	}

	@Override
	public String loginout(JSONObject json) {
		try {
			if (!json.containsKey("userName") || json.getString("userName").equals("")) {
				log.warn("loginout[参数userName错误]");
				return StatusCode.PARAM_ERROR.toJSON("参数 用户名 错误");
			}
			if (checkSessionId(json)) {
				log.warn("cookie对应不上，错误的请求");
				return StatusCode.SUCCESS.toJSON();
			}
			String sessionId = webUserDAO.redis_get(RedisConstant.LIVING + json.getString("userName"));
			if (sessionId == null) {
				log.warn(json.getString("userName") + "用户过期");
				return StatusCode.SUCCESS.toJSON();
			}
			if (!sessionId.equals(json.getString("get_sessionId"))) {
				log.warn(json.getString("userName") + "用户被踢");
				return StatusCode.SUCCESS.toJSON();
			}
			if (webUserDAO.redis_del(RedisConstant.LIVING + json.getString("userName"))) {
				return StatusCode.SUCCESS.toJSON();
			} else {
				log.warn("删除redis用户失败");
				return StatusCode.SYSTEM_EXCEPTION.toJSON();
			}
		} catch (Exception e) {
			log.error(e.getMessage(), e);
			return StatusCode.SYSTEM_EXCEPTION.toJSON();
		}
	}

	private Boolean checkSessionId(JSONObject json) {
		if (json.containsKey("get_sessionId")) {
			final String userName = json.getString("userName");
			String old_sessionId = webUserDAO.redis_get(RedisConstant.SESSIONID + userName);
			if (old_sessionId != null) {
				if (old_sessionId.equals(json.getString("get_sessionId"))) {
					webUserDAO.redis_set(RedisConstant.SESSIONID + userName, json.getString("set_sessionId"));
					webUserDAO.redis_expire(RedisConstant.SESSIONID + userName, PAGE_TIMEOUT);
					return false;
				}
			}
		}
		return true;
	}

	private void setSessionId(JSONObject json) {
		webUserDAO.redis_set(RedisConstant.SESSIONID + json.getString("userName"), json.getString("set_sessionId"));
		webUserDAO.redis_expire(RedisConstant.SESSIONID + json.getString("userName"), PAGE_TIMEOUT);
	}

	@Override
	public String submitInfo(JSONObject json) {
		try {
			if (!json.containsKey("userName") || json.getString("userName").equals("")) {
				log.warn("submitInfo[参数userName错误]");
				return StatusCode.PARAM_ERROR.toJSON("参数 用户名 错误");
			}
			if (checkSessionId(json)) {
				log.warn("cookie对应不上，错误的请求");
				return StatusCode.SESSION_OUT_OF_DATE.toJSON();
			}
			if (!json.containsKey("phone") || json.getString("phone").length() != 11) {
				log.warn("submitInfo[参数phone错误]");
				return StatusCode.PARAM_ERROR.toJSON("参数 联系电话 错误");
			}
			if (!json.containsKey("tbUserName") || json.getString("tbUserName").equals("")) {
				log.warn("submitInfo[参数tbUserName错误]");
				return StatusCode.PARAM_ERROR.toJSON("参数 姓名 错误");
			}
			if (!json.containsKey("dealerID") || json.getString("dealerID").equals("")) {
				log.warn("submitInfo[参数dealerID错误]");
				return StatusCode.PARAM_ERROR.toJSON("参数 渠道id 错误");
			}
			if (!json.containsKey("cityCode") || json.getString("cityCode").equals("")) {
				log.warn("submitInfo[参数cityCode错误]");
				return StatusCode.PARAM_ERROR.toJSON("参数 城市code 错误");
			}
			if (!json.containsKey("cityName") || json.getString("cityName").equals("")) {
				log.warn("submitInfo[参数cityName错误]");
				return StatusCode.PARAM_ERROR.toJSON("参数 城市名称 错误");
			}
			// if(!json.containsKey("papersCode") ||
			// json.getString("papersCode").equals("")){
			// log.info("submitInfo[参数papersCode错误]");
			// return StatusCode.PARAM_ERROR.toJSON("参数 身份证号 错误");
			// }
			// if(!json.containsKey("wxID") ||
			// json.getString("wxID").equals("")){
			// log.info("submitInfo[参数wxID错误]");
			// return StatusCode.PARAM_ERROR.toJSON("参数 微信ID 错误");
			// }
			// if(!json.containsKey("aliID") ||
			// json.getString("aliID").equals("")){
			// log.info("submitInfo[参数aliID错误]");
			// return StatusCode.PARAM_ERROR.toJSON("参数 支付宝ID 错误");
			// }
			// if(!json.containsKey("popChannel") ||
			// json.getString("popChannel").equals("")){
			// log.info("submitInfo[参数popChannel错误]");
			// return StatusCode.PARAM_ERROR.toJSON("参数 推广渠道 错误");
			// }
			if (!json.containsKey("isMain") || !"1,2".contains(json.getString("isMain"))) {
				log.warn("submitInfo[参数isMain错误]");
				return StatusCode.PARAM_ERROR.toJSON("参数 是否作为主账户 错误");
			}
			// if(!json.containsKey("headPopChannel") ||
			// json.getString("headPopChannel").equals("")){
			// log.info("submitInfo[参数popChannel错误]");
			// return StatusCode.PARAM_ERROR.toJSON("参数总部推广渠道 错误");
			// }
			// if(!json.containsKey("remarks") ||
			// json.getString("remarks").equals("")){
			// log.info("submitInfo[参数remarks错误]");
			// return StatusCode.PARAM_ERROR.toJSON("参数 备注 错误");
			// }

			String userLoginTime = webUserDAO.redis_get(RedisConstant.LIVING + json.getString("userName"));
			if (userLoginTime == null) {
				log.warn(json.getString("userName") + "用户过期");
				return StatusCode.SESSION_OUT_OF_DATE.toJSON("用户过期,请重新登录");
			}

			Merchant merchantInfo = webUserDAO.getMerchantTypeId(json.getString("dealerID").toUpperCase());
			if (merchantInfo == null) {
				log.warn(json.getString("dealerID") + "商户不存在");
				return StatusCode.USER_NOT_FOUND.toJSON("商户不存在");
			}

			Boolean checkphone = webUserDAO.checkPhone(json.getString("phone"));
			if (checkphone == null) {
				log.warn("db error");
				return StatusCode.SYSTEM_EXCEPTION.toJSON();
			}
			if (checkphone) {
				log.warn(json.getString("phone") + "phone 已经存在");
				return StatusCode.USERNAME_EXISTED.toJSON("该号码正在使用中");
			}

			final String userId = getUserId();
			String invite = userDAO.getInviteCode();
			if (invite == null) {
				log.error("getInviteCode return null," + json);
				return StatusCode.SYSTEM_EXCEPTION.toJSON();
			}
			final String papersCode = json.getString("papersCode");
			final String remarks = json.getString("remarks");
			long time = Clock.systemDefaultZone().millis();

			User user = new User();
			user.setUserId(userId);
			user.setUserName(json.getString("tbUserName"));
			user.setDealerId(json.getString("dealerID").toUpperCase());
			user.setPhone(json.getString("phone"));
			user.setCityCode(json.getString("cityCode"));
			user.setCityName(json.getString("cityName"));
			user.setAlipayUserId(json.getString("aliID"));
			user.setWeixinUserId(json.getString("wxID"));
			user.setIsMain(json.getIntValue("isMain"));
			user.setCreateTime(time);
			user.setLastTime(time);
			user.setUserTypeId(merchantInfo.getUserTypeId());
			user.setInviteCode(invite);
			user.setMerchantId(merchantInfo.getMerchantId());
			boolean res = webUserDAO.insertUserInfo(user, papersCode, remarks, merchantInfo.getCityCode());
			if (!res) {
				log.warn("插入数据库失败");
				return StatusCode.SYSTEM_EXCEPTION.toJSON();

			}
			sendMsg(json.getString("phone"), MSG_INGO);
			// 发送欢迎消息
			addWelcomeMsg(userId, user.getIsMain() == 1 ? 1 : 0, user.getDetailType());
			return StatusCode.SUCCESS.toJSON();
		} catch (Exception e) {
			log.error(e.getMessage(), e);
			return StatusCode.SYSTEM_EXCEPTION.toJSON();
		}
	}

	@Override
	public String submitMerchantInfo(JSONObject json) {
		try {
			if (!json.containsKey("userName") || json.getString("userName").equals("")) {
				log.warn("submitInfo[参数userName错误]");
				return StatusCode.PARAM_ERROR.toJSON("参数 用户名 错误");
			}
			if (checkSessionId(json)) {
				log.warn("cookie对应不上，错误的请求");
				return StatusCode.SESSION_OUT_OF_DATE.toJSON();
			}
			if (!json.containsKey("userType") || !"11,12,13,14,15".contains(json.getString("userType"))) {
				log.warn("submitInfo[参数userType错误]");
				return StatusCode.PARAM_ERROR.toJSON("参数 用户类别 错误");
			}
			if (!json.containsKey("merchantType") || !"1,2".contains(json.getString("merchantType"))) {
				log.warn("submitInfo[参数merchantType错误]");
				return StatusCode.PARAM_ERROR.toJSON("参数 商户类型 错误");
			}
			if (!json.containsKey("dealerID") || json.getString("dealerID").equals("")) {
				log.warn("submitInfo[参数dealerID错误]");
				return StatusCode.PARAM_ERROR.toJSON("参数 渠道id 错误");
			}
			if (!json.containsKey("popChannel") || json.getString("popChannel").equals("")) {
				log.warn("submitInfo[参数popChannel错误]");
				return StatusCode.PARAM_ERROR.toJSON("参数 推广渠道 错误");
			}
			if (!json.containsKey("headPopChannel") || json.getString("headPopChannel").equals("")) {
				log.warn("submitInfo[参数popChannel错误]");
				return StatusCode.PARAM_ERROR.toJSON("参数总部推广渠道 错误");
			}
			if (!json.containsKey("tradeScope") || json.getString("tradeScope").equals("")) {
				log.warn("submitInfo[参数tradeScope错误]");
				return StatusCode.PARAM_ERROR.toJSON("业务范围 错误");
			}
			if (!json.containsKey("scopeName") || json.getString("scopeName").equals("")) {
				log.warn("submitInfo[参数scopeName错误]");
				return StatusCode.PARAM_ERROR.toJSON("区域 错误");
			}
			final String address = json.getString("address");
			final String storeAddress = json.getString("storeAddress");
			if (address == null) {
				log.warn("param address error");
				return StatusCode.PARAM_ERROR.toJSON("证件地址不存在");
			}
			if (StringUtils.isBlank(storeAddress)) {
				log.warn("param storeAddress error");
				return StatusCode.PARAM_ERROR.toJSON("门店地址不存在");
			}
			final String storeAddressDb = storeAddress.replaceAll("\r", "").replaceAll("\n", "");
			if (storeAddressDb.length() < 8) {
				log.warn("门店地址长度至少8位," + storeAddress);
				return StatusCode.PARAM_ERROR.toJSON("门店地址至少8位");
			}
			// final int attribute = json.getIntValue("attribute");
			// if(attribute <1 || attribute>4){
			// log.info("商户售卡属性错误，"+attribute);
			// return StatusCode.PARAM_ERROR.toJSON();
			// }

			String userLoginTime = webUserDAO.redis_get(RedisConstant.LIVING + json.getString("userName"));
			if (userLoginTime == null) {
				log.warn(json.getString("userName") + "用户过期");
				return StatusCode.SESSION_OUT_OF_DATE.toJSON("用户过期,请重新登录");
			}

			Integer res = webUserDAO.checkMerchantDealerId(json.getString("dealerID"));
			if (ObjectUtils.isNull(res)) {
				log.warn("DB error");
				return StatusCode.SYSTEM_EXCEPTION.toJSON();
			}
			if (res > 0) {
				log.warn(json.getString("dealerID") + "dealerId 已经存在");
				return StatusCode.USERNAME_EXISTED.toJSON("dealerID 已存在");
			}

			final long time = Clock.systemDefaultZone().millis();
			String merchantId = "YT" + DateUtils.format(time, "yyMMddHHmmss") + StringUtil.randomNumberString(6);
			SelfRegistering s = new SelfRegistering();
			s.setUser_type_id(json.getIntValue("userType"));
			s.setDealer_id(json.getString("dealerID").toUpperCase());
			s.setCompany_name(json.getString("companyName"));
			s.setIdCard(json.getString("businessLicence"));
			s.setStoreAddress(storeAddressDb);
			s.setAddress(json.getString("address").replaceAll("\r", "").replaceAll("\n", ""));
			s.setPopchannel(json.getString("popChannel"));
			s.setHead_popchannel(json.getString("headPopChannel"));
			s.setDevMacAddress(json.getString("devMac"));
			s.setMerchantType(json.getIntValue("merchantType"));
			s.setPopchannel_name(json.getString("popChannelName"));
			s.setHead_popchannel_name(json.getString("headPopChannelName"));

			/********************** Model继承17-10-26 ***************************/
			ModelInfo modelInfo = userDAO.getDealerModel(json.getString("popChannel"));
			if (ObjectUtils.isNull(modelInfo)) {
				log.info("getDealerModel return null," + json.getString("popChannel"));
				return StatusCode.SYSTEM_EXCEPTION.toJSON();
			}
			s.setPhoneModel(modelInfo.getPhoneModel());
			s.setDiscountModel(modelInfo.getDiscountModel());
			s.setTransterModel(modelInfo.getIncomeTransterModel());
			s.setPackModel(modelInfo.getPackModel());
			s.setDwkModel(modelInfo.getDwkModel());
			s.setWhiteCardPay(modelInfo.getWhiteCardPay());
			s.setWhiteCardReturn(modelInfo.getWhiteCardReturn());
			s.setCheckLocationFlag(modelInfo.getCheckLocationFlag());
			s.setCheckLocation(modelInfo.getCheckLocation());
			/********************** Model继承17-10-26 ***************************/
			// 售卡权限+范围把之前merchant_attribute修改为 type+scope两个字段
			int type = json.getIntValue("tradeScope");// 业务范围；1远特，2联通，3移动，4电信
			String scope = json.getString("scopeName").substring(0, 2);// 业务范围；北京市，江苏省
			Scope checkScope = webUserDAO.checkScope(type, scope);// 校验售卡权限+区域
																	// 数据库是否有
			if (StringUtil.isNULL(checkScope)) {
				log.warn("submitInfo[参数tradeScope：scopeName错误]" + type + ":" + scope);
				return StatusCode.PARAM_ERROR.toJSON("营运商和区域对应位置编号不存在");
			}
			String newPhoneModel = getModelStr(s.getPhoneModel(), checkScope.getPhoneModel());
			String newPackModel = getModelStr(s.getPackModel(), checkScope.getPackModel());
			s.setPhoneModel(newPhoneModel);
			s.setPackModel(newPackModel);

			s.setMerchant_attribute(type);// 维护merchant_attribute
			s.setScope(scope);
			s.setType(type);
			s.setModifyTime(time);
			s.setMerchantId(merchantId);
			s.setIsManage(2);// 后台激活的商户 标识为2
			boolean r = webUserDAO.insertMerchantInfo(s);

			if (!r) {
				log.warn("插入商户数据返回false，" + s.toString());
				return StatusCode.SYSTEM_EXCEPTION.toJSON();
			}
			// 添加特殊商户信息 如新零售
			addSpecialDealerModel(s.getPopchannel(), s.getDealer_id(), s.getCompany_name());
			//限制权限的控制
			addLimitPower(s, modelInfo);
			// sendMsg(phone, MSG_INGO);
			return StatusCode.SUCCESS.toJSON();
		} catch (Exception e) {
			log.error(e.getMessage(), e);
			return StatusCode.SYSTEM_EXCEPTION.toJSON();
		}
	}

	@Override
	public String checkDealerId(JSONObject json) {
		try {
			if (!json.containsKey("userName") || json.getString("userName").equals("")) {
				log.warn("submitInfo[参数userName错误]");
				return StatusCode.PARAM_ERROR.toJSON("参数 用户名 错误");
			}
			if (checkSessionId(json)) {
				log.warn("cookie对应不上，错误的请求");
				return StatusCode.SESSION_OUT_OF_DATE.toJSON();
			}
			if (!json.containsKey("dealerID") || json.getString("dealerID").equals("")) {
				log.warn("submitInfo[参数dealerID错误]");
				return StatusCode.PARAM_ERROR.toJSON("参数 渠道id 错误");
			}

			String userLoginTime = webUserDAO.redis_get(RedisConstant.LIVING + json.getString("userName"));
			if (userLoginTime == null) {
				log.info(json.getString("userName") + "用户过期");
				return StatusCode.SESSION_OUT_OF_DATE.toJSON("用户过期,请重新登录");
			}

			Integer res = webUserDAO.checkMerchantDealerId(json.getString("dealerID").toUpperCase());
			if (res != null) {
				StringBuilder r = new StringBuilder(128);
				r.append("{\"type\":\"" + res + "\"}");
				return StatusCode.SUCCESS.toDiyJson("data", r);
			} else {
				return StatusCode.SYSTEM_EXCEPTION.toJSON();
			}
		} catch (Exception e) {
			log.error(e.getMessage(), e);
			return StatusCode.SYSTEM_EXCEPTION.toJSON();
		}
	}

	@Override
	public String findScopePool(JSONObject json) {
		if (checkSessionId(json)) {
			log.warn("cookie对应不上，错误的请求");
			return StatusCode.SESSION_OUT_OF_DATE.toJSON();
		}
		List<Scope> sopes = webUserDAO.findScopePool();
		if (sopes == null) {
			log.error("db connection error");
			return StatusCode.SYSTEM_EXCEPTION.toJSON();
		}
		if (sopes.size() < 1) {
			log.warn("tb_sell_scope_pool nothing record");
			return StatusCode.SUCCESS.toJSON("数据库表无数据，请联系管理员");
		}
		// 程序中分组容器
		HashMap<Integer, List<Scope>> hashMap = new HashMap<>();
		for (Scope sp : sopes) {
			Integer type = sp.getType();
			if (!hashMap.keySet().contains(type)) {
				ArrayList<Scope> scopesItem = new ArrayList<Scope>();
				hashMap.put(type, scopesItem);
			}
			List<Scope> list = hashMap.get(type);
			list.add(sp);
		}
		// 分组后组装json数据
		JSONObject obj = new JSONObject();
		for (Entry<Integer, List<Scope>> entry : hashMap.entrySet()) {
			Integer key = entry.getKey();
			List<Scope> value = entry.getValue();
			JSONArray arr1 = new JSONArray();
			for (Scope scope : value) {
				JSONObject obj1 = new JSONObject();
				obj1.put("scopeId", scope.getScopeId());
				obj1.put("area", scope.getArea());
				arr1.add(obj1);
			}
			obj.put(String.valueOf(key), arr1);
		}
		return StatusCode.SUCCESS.toDiyJson("data", obj);
	}
}
